// Game类    表示整个游戏类
// @snake    表示蛇的实例
// @map    地图实例
// @food    食物实例
// @block    障碍物实例

function Game(snake, map, food, block) {
    // 接收数据
    this.snake = snake;
    this.map = map;
    this.food = food;
    this.bolck = block;
    // 定义定时器的句柄
    this.timer  = null;
    // 定义标记
    this.flag = null;

    // 执行初始化方法
    this.init();
}

// 定义初始化方法
Game.prototype.init = function() {
    // 渲染地图
    this.renderMap();
    // 渲染食物
    this.renderFood();
    // 渲染蛇
    this.renderSnake();
    // 执行start方法
    this.start();
    // 执行bindEvent方法
    this.bindEvent();
}

// 渲染地图方法
Game.prototype.renderMap = function() {
    // 调用了map的fill方法
    this.map.fill();
}

// 渲染食物
Game.prototype.renderFood = function() {
    // 所谓渲染食物就是在地图中找到坐标元素即可
    // 获取食物坐标
    var x = this.food.x;
    var y = this.food.y;
    // 可以利用数组映射dom元素
    this.map.arr[x][y].style.backgroundColor = 'red';
}

// 渲染蛇
Game.prototype.renderSnake = function() {
    // 所谓渲染蛇  可以理解为在地图中渲染多个食物组成的元素坐标即可
    // 遍历蛇数组
    for (var i = 0; i < this.snake.arr.length; i++) {
        // 获取坐标值
        var x = this.snake.arr[i].x;
        var y = this.snake.arr[i].y;

        // 在地图中渲染对应的坐标即可
        this.map.arr[x][y].style.backgroundColor  = 'green';
    }
}

// 定义清屏方法
    Game.prototype.clear = function() {
        this.map.clear();
    }


// 开始游戏
Game.prototype.start = function() {
    // 游戏结束标记为true
    this.flag = true;
    // 缓存this
    var me = this;
    // 赋值定时器
    this.timer = setInterval(function() {
        // 清屏
        me.clear();
        // 移动
        me.snake.move();

        // 检侧是否撞墙
        me.checkMap();

        // 检侧是否吃到食物
        me.checkFood();
        // 检侧蛇是否吃到自己
        me.checkSnake();

        // 判断游戏是否正常执行
        if (me.flag) {
            // 清屏
            me.clear();
            // 渲染蛇
        me.renderSnake();
        // 渲染食物
        me.renderFood();
        }
        
    }, 200)
}


// 绑定事件
    Game.prototype.bindEvent = function() {
        // 缓存this
        var me = this;
        // 为document绑定键盘事件
        document.onkeydown = function(e) {
            // 获取按下的方向键
            var key = e.keyCode;
            // 判断
            if (key === 37 || key === 38 || key === 39 || key === 40) {
                // 改变蛇的方向
                me.snake.change(key);
            }
        }
    }


    // 定义游戏结束
    Game.prototype.gameOver = function() {
        // 游戏结束定义false
        this.flag = false;
        // 停止定时器
        clearInterval(this.timer);
        // 弹出提示
        alert('游戏结束');
    }


    // 检侧蛇是否撞墙
    Game.prototype.checkMap = function() {
        // 获取蛇的头部
        var head = this.snake.arr[this.snake.arr.length - 1];

        // 判断
        if (head.x < 0 || head.x >= this.map.col || head.y < 0 || head.y >= this.map.row) {
            console.log('撞墙了');
            // 执行结束游戏的方法
            this.gameOver();
        }
    }

    // 重置食物
    Game.prototype.resetFood = function() {
        // 随机生成x 和y;
        var x = parseInt(Math.random() * this.map.row);
        var y = parseInt(Math.random() * this.map.col);

        // 因为在地图中不仅有食物  还有蛇的存在  为了防止吃到食物之后  食物跑到蛇身上 因此要做判断
        // 可以拿着食物的坐标与蛇身上的每一节身体坐标做匹配
        for (var i = 0; i < this.snake.arr.length; i++) {
            // 定义遍历简化书写
            var one = this.snake.arr[i];
            // 判断是否匹配
            if (one.x === x && one.y === y) {
                // 递归处理
                this.resetFood();
                // 终止代码执行
                return alert('食物重置到蛇身上了');
            }
        }
        // 本质是找到了food上面的resetFood方法
        this.food.resetFood(x, y);
    }


    // 检侧是否吃到了食物
    Game.prototype.checkFood = function() {
        // 获取蛇的头部
        var head = this.snake.arr[this.snake.arr.length - 1];

        // 获取食物坐标
        var x = this.food.x;
        var y = this.food.y;

        // 比较
        if (head.x === x && head.y === y) {
            // 蛇要生长
            this.snake.growUp();
            // 重置食物方法
            this.resetFood();
        }
    }



    // 检侧蛇是否吃到自己
    Game.prototype.checksnake = function() {
        // 获取蛇的头部
        var head = this.snake.arr[this.snake.arr.length - 1];

        // 拿着蛇的头部与蛇的每一节身体做匹配
        for (var i = 0; i < this.snake.arr.length - 1; i++); {
            // 定义变量  简化书写
            var one = this.snake.arr[i];

            // 比较
            if (head.x === one.x && head.y === one.y) {
                // 游戏结束
                this.gameOver();
            }
        }
    }
